/*
 * ClassDetails.cpp
 *
 *  Created on: Jan 1, 2009
 *      Author: sez
 */

#include "ClassDetails.h"
#include "Power.h"
#include "CharacterRecord.h"
#include "DndData.h"

#include <Xml/Xml.h>
#include <Xml/XmlPath.h>

ClassDetails::ClassDetails(const QString &title)
	: TitledData(title)
{
}

ClassDetails::ClassDetails(const ClassDetails &rhs)
    : TitledData(rhs.title())
{
    this->className = rhs.className;
    this->role = rhs.role;
    this->powerSource = rhs.powerSource;
    this->armourProficiencies = rhs.armourProficiencies;
    this->weaponProficiencies = rhs.weaponProficiencies;
    this->implement = rhs.implement;
    this->defenceBonus = rhs.defenceBonus;
    this->hitPointsBase = rhs.hitPointsBase;
    this->hitPointsPerLevel = rhs.hitPointsPerLevel;
    this->healingSurgesPerDay = rhs.healingSurgesPerDay;
    this->fixedSkills = rhs.fixedSkills;
    this->classSkills = rhs.classSkills;
    this->buildOptions = rhs.buildOptions;
    this->classFeatures = rhs.classFeatures;
}

ClassDetails::~ClassDetails() {
}

QString ClassDetails::description() const
{
    return QString("%1 %2").arg(Power::POWER_SOURCE_NAMES[powerSource]).arg(DndData::ROLE_NAMES[role]);
}

ClassDetails &ClassDetails::operator=(const ClassDetails &rhs)
{
    this->className = rhs.className;
    this->role = rhs.role;
    this->powerSource = rhs.powerSource;
    this->armourProficiencies = rhs.armourProficiencies;
    this->weaponProficiencies = rhs.weaponProficiencies;
    this->implement = rhs.implement;
    this->defenceBonus = rhs.defenceBonus;
    this->hitPointsBase = rhs.hitPointsBase;
    this->hitPointsPerLevel = rhs.hitPointsPerLevel;
    this->healingSurgesPerDay = rhs.healingSurgesPerDay;
    this->fixedSkills = rhs.fixedSkills;
    this->classSkills = rhs.classSkills;
    this->buildOptions = rhs.buildOptions;
    this->classFeatures = rhs.classFeatures;
    return *this;
}

void ClassDetails::saveToXml() const
{
    Xml xml(XmlPath(XmlPath::CLASS_BASE, XmlPath::safeDataPathName(title())));
    xml.appendTag("Title", title());
    appendTag(xml, "ClassName", className);
    appendTag(xml, "Role", role);
    appendTag(xml, "PowerSource", powerSource);
    xml.appendArray("ArmourProficiencies", armourProficiencies);
    xml.appendArray("WeaponProficiencies", weaponProficiencies);
    xml.appendArray("Implement", implement);
    appendTitleArray(xml, "DefenceBonus", defenceBonus);
    appendTag(xml, "HitPointsBase", hitPointsBase);
    appendTag(xml, "HitPointsPerLevel", hitPointsPerLevel);
    appendTag(xml, "HealingSurgesPerDay", healingSurgesPerDay);
    appendArray(xml, "FixedSkills", fixedSkills);
    appendArray(xml, "ClassSkills", classSkills);
    xml.appendArray("BuildOptions", buildOptions);
    appendTitleArray(xml, "ClassFeatures", classFeatures);
    xml.serializeXml();
}

void ClassDetails::loadFromXml()
{
    Xml xml(XmlPath(XmlPath::CLASS_BASE, XmlPath::safeDataPathName(title())));
    xml.deserializeXml();
    setTitle(xml.value("Title"));
    className = value<DndData::ClassName>(xml, "ClassName");
    role = value<DndData::PartyRole>(xml, "Role");
    powerSource = value<Power::PowerSource>(xml, "PowerSource");
    armourProficiencies = xml.valueArray("ArmourProficiencies");
    weaponProficiencies = xml.valueArray("WeaponProficiencies");
    implement = xml.valueArray("Implement");
    defenceBonus = valueTitleArray<Trait>(xml, "DefenceBonus");
    hitPointsBase = value<int>(xml, "HitPointsBase");
    hitPointsPerLevel = value<int>(xml, "HitPointsPerLevel");
    healingSurgesPerDay = value<int>(xml, "HealingSurgesPerDay");
    fixedSkills = valueArray<DndData::SkillTypes>(xml, "FixedSkills");
    classSkills = valueArray<DndData::SkillTypes>(xml, "ClassSkills");
    buildOptions = xml.valueArray("BuildOptions");
    classFeatures = valueTitleArray<Trait>(xml, "ClassFeatures");
}

void ClassDetails::fill(CharacterRecord *record)
{
    record->setClassName(title());
    QList<Trait>::const_iterator it = defenceBonus.constBegin();
    for ( ; it != defenceBonus.constEnd(); ++it )
        (*it).apply(record);
    record->setBaseHitPoints(hitPointsBase);
    record->setHitPointsPerLevel(hitPointsPerLevel);
    record->setSurgesPerDayBase(healingSurgesPerDay);
}
